package lar.system.engine;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Map.Entry;
import java.util.Stack;
import java.util.TreeMap;
import java.util.Vector;
import java.util.Map.Entry;

import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGL11;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLContext;
import javax.microedition.khronos.egl.EGLDisplay;

import lar.system.opengl.Drawable;
import lar.system.opengl.GLKeyHandler;
import lar.system.opengl.GLRenderer;
import lar.system.opengl.MultisampleConfigChooser;

import android.annotation.SuppressLint;
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.preference.MultiSelectListPreference;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;

public class UI extends GLSurfaceView
{
	public static Stack<Vector<Pair<TouchListener, Drawable>>> listenerStack = null;
	public GLRenderer renderer;
	public GLKeyHandler keyHandler;
	private static Vector<Pair<TouchListener, Drawable>> listeners=null;
	public static boolean loaded = false;
	public static boolean keyboard = false;
	private TouchListener GUILock=null;
	public static boolean needRendering = false;
	
	public UI(Context context) 
	{
		super(context);
		loaded = false;
		keyHandler = null;
		if(listeners == null) listeners = new Vector<Pair<TouchListener, Drawable>>();
		setEGLContextClientVersion(1);
		//setEGLConfigChooser(new MultisampleConfigChooser());
		renderer = new GLRenderer(context);
		setRenderer(renderer);
		setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
		if(listenerStack == null) listenerStack = new Stack<Vector<Pair<TouchListener,Drawable>>>();
		setFocusable(true);
		setFocusableInTouchMode(true);
		setKeepScreenOn(true);
		
	}
	
	/*
	public UI(Context context, UI other) 
	{
		super(context);
		Px=Py=0;
		keyHandler = null;
		listeners = other.listeners;
		setEGLContextClientVersion(1);
		setEGLConfigChooser(new MultisampleConfigChooser());
		renderer = new GLRenderer(context);
		setRenderer(renderer);
		setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
		if(listenerStack == null) listenerStack = new Stack<Vector<Pair<TouchListener,Drawable>>>();
		setFocusable(true);
		setFocusableInTouchMode(true);
	}*/
	
	public void lockUI(TouchListener tl)
	{
		this.GUILock = tl;
	}
	
	public TouchListener getGUILock()
	{
		return this.GUILock;
	}
	
	public void setKeyHandler(GLKeyHandler keyHandler)
	{
		this.keyHandler = keyHandler;
	}
	
	
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) 
	{
		UI.needRendering = true;
		if(this.keyHandler != null) this.keyHandler.onKeyDown(keyCode, event);
		return super.onKeyDown(keyCode, event);
	}
	
	public void ClearListeners()
	{
		listeners.clear();
	}
	
	public void showKeyboard()
	{
		keyboard = true;
		MainProgram.hideBanner();
		//((InputMethodManager) MainProgram.currentActivity.getSystemService(Context.INPUT_METHOD_SERVICE)).showSoftInput(MainProgram.glSurfaceView, 0);
	}
	
	public void hideKeyboard()
	{
		this.keyHandler = null; 
		keyboard = false;
		
		//((InputMethodManager) MainProgram.currentActivity.getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(MainProgram.glSurfaceView.getWindowToken(), 0);
	}
	
	public void PushClearListeners()
	{
		listenerStack.push(new Vector<Pair<TouchListener, Drawable>>(listeners));
		ClearListeners();
	}
	
	public void PopClearListeners()
	{
		ClearListeners();
		listeners = listenerStack.pop();
	}
	
	public void addTouchListener(TouchListener tl, Drawable d)
	{
		if(tl == null) return;
		listeners.add(new Pair<TouchListener, Drawable>(tl, d));
	}
	
	public void removeTouchListener(TouchListener tl)
	{
		for(Pair<TouchListener, Drawable> p : listeners) 
		{
			if(p.getL() == tl) 
			{
				listeners.remove(p);
				return;
			}
		}
	}
	
	public float getAspectRatio()
	{
		return (float)this.getWidth() / (float)this.getHeight();
	}
	
	public boolean onTouchEvent(MotionEvent e)
	{
		//hideKeyboard();
		//keyHandler = null;
		synchronized(GameLoop.stateLock)
		{
			UI.needRendering = true;
			float x=e.getX();
			float y=e.getY();
			float aspect = getAspectRatio();
			float gl_x = 2*(x / (float)this.getWidth())-1;
			gl_x *= aspect;
			float gl_y = -2*(y / (float)this.getHeight())+1;
			
			if(this.GUILock != null) 
			{
				this.GUILock.onTouchEvent(e);
				return true;
			}
			if(gl_y >= -0.2 && keyboard) hideKeyboard();
			if(gl_y < -0.2 && keyboard)
			{
				//Log.d("R", "handler: " + this.keyHandler);
				if(e.getAction() != MotionEvent.ACTION_UP) return true;
				if(this.keyHandler == null) hideKeyboard();
				else
				{
					Keyboard.keyEvent(this.keyHandler, x/(float)getWidth(), (1-y/(float)getHeight())/0.4f);
					needRendering = true;
				}
				return true;
			}
			for (int i = listeners.size()-1; i >= 0; i--)
			{
				Pair<TouchListener, Drawable> p = listeners.elementAt(i);
				Drawable d = p.getR();
				boolean bounds = d.CheckBounds(gl_x, gl_y);
				if(!bounds) continue;
				TouchListener tl = p.getL();
				try 
				{
					tl.onTouchEvent(e);
				}catch(Exception ex)
				{
					StringWriter sw = new StringWriter();
					PrintWriter pw = new PrintWriter(sw);
					ex.printStackTrace(pw);
					MainProgram.MessageBox(sw.toString()); 
					ex.printStackTrace();
				}
					
				break;
			}
		}
		return true;
	}
	
}
